#!/usr/bin/env bash

# CLASS WORK >

function work.throw() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare -i OPTIND=0
	declare OPTARG
	declare OPTERR
	declare optstring="e:"

	declare option

	while getopts ${optstring} option
	do
		case ${option} in
			# $option $OPTARG $OPTIND
			e )
				exeStatus=$OPTARG
				;;
		esac
	done
	
	shift $(($OPTIND - 1))
	
	if (( $# > 0 ))
	then
		printf "$@"
	fi
	
	return $exeStatus
}

function work.escapeSpaces() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS
	
	declare word
	declare outPut
	declare -i paramIte=1
	
	for word in $@
	do
		if (( paramIte != $# ))
		then
			outPut="${outPut}${word}\\ "
		else
			outPut="${outPut}${word}"
		fi
		(( paramIte++ ))
	done
	
	echo $outPut
	
	return $exeStatus
}

function work.help() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.create() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS
	
	declare -r thisScript="stdwork.sh"
	declare -a directories=( bin doc download etc extra lib proyects share share/proyects svnserve tmp var var/log var/run var/www )
	
	work.createDirectories -p $WORKBASE ${directories[@]}
	
	if [ "${thisScript}" -nt "${WORKBASE}/bin/${thisScript}" ]
	then
		cp -f $thisScript "${WORKBASE}/bin"
	fi
	
	return $exeStatus
}

function work.getProcessesId() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare -i OPTIND=0
	declare OPTARG
	declare OPTERR
	declare optstring="s:v"

	declare option
	declare verbose=$FALSE
	declare separator
	
	declare regExp
	declare processList

	while getopts ${optstring} option
	do
		case ${option} in
			# $option $OPTARG $OPTIND
			s )
				separator=$OPTARG
				;;
			v )
				separator=','
				verbose=$TRUE
				;;
		esac
	done

	shift $(($OPTIND - 1))
	
	if (( $# > 0))
	then
		regExp=$@
		processList=$(ps ax|grep $regExp|grep -v grep|\
									cut --delimiter=' ' --field=2)
		
		if [ "$verbose" == "$TRUE" ]
		then
			separator=','
			processList=$(echo $processList | sed "s/ /$separator/g")
			
			ps "w$processList"
		else
			if [ -n "$separator" ]
			then
				processList=$(echo $processList | sed "s/ /$separator/g")
			fi
			
			echo "$processList"
		fi
		
		exeStatus=$?
	else
		work.throw -e 1 \
			'Error: You have to specified a search pattern to look for\n'
		exeStatus=$?
	fi
	
	return $exeStatus
}

function work.createFiles() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare -i OPTIND=0
	declare OPTARG
	declare OPTERR
	declare optstring="p:"

	declare option
	declare baseDirectory
	declare fullFile

	while getopts ${optstring} option
	do
		case ${option} in
			# $option $OPTARG $OPTIND
			p )
				baseDirectory=$OPTARG
				;;
		esac
	done

	shift $(($OPTIND - 1))

	for file in $@
	do
		if [ -n "${baseDirectory}" ]
		then
			fullFile="${baseDirectory}/${file}"
		else
			fullFile=$file
		fi

		touch $fullFile
		exeStatus=$?; if ((exeStatus != 0)); then break; fi

		# CHECK IF IT IS A SHELL SCRIPT (sh EXTENSION), IF SO, MAKE IT EXECUTABLE
		if [ "$(echo $fullFile | grep .sh)" != '' ]
		then
			chmod +x $fullFile
			exeStatus=$?; if ((exeStatus != 0)); then break; fi
		fi
	done

	return $exeStatus
}

function work.createDirectories() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare -i OPTIND=0
	declare OPTARG
	declare OPTERR
	declare -r optstring="p:"

	declare option
	declare baseDirectory
	declare fullDirectory

	while getopts $optstring option
	do
		case $option in
			# $option $OPTARG $OPTIND
			p )
				baseDirectory=$OPTARG
				;;
		esac
	done

	shift $(($OPTIND - 1))

	for directory in $@
	do
		if [ -n "${baseDirectory}" ]
		then
			fullDirectory="${baseDirectory}/${directory}"
		else
			fullDirectory=$directory
		fi

		mkdir -p $fullDirectory
		exeStatus=$?; if ((exeStatus != 0)); then break; fi
	done

	return $exeStatus
}

function work.createSymlinks() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS
	declare -i symlinkIte

	if (( $# % 2 == 0 ))
	then
		for ((symlinkIte=$#; symlinkIte > 0; symlinkIte-=2))
		do
			ln -s $1 $2
			exeStatus=$?; if ((exeStatus != 0)); then break; fi
			shift 2
		done
	fi

	return $exeStatus
}

# < CLASS WORK

# CLASS WORK.PROYECT >

function work.proyect.help() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.cd() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.create() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.delete() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.exeCmd() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.exist() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.info() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.help.list() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	return $exeStatus
}

function work.proyect.create() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare -i OPTIND=0
	declare OPTARG
	declare OPTERR
	declare optstring="p:s:n:d:u:"
	
	# FUNCTION PARAMETERS >
	declare proyectId # p
	declare svnURL # s
	declare svnUsername # u
	declare infoProyectName # n
	declare infoProyectDescription # d
	# < FUNCTION PARAMETERS
	
	declare svnParams
	declare proyectDir
	declare -a proyectDirectories
	declare -a proyectFiles
	declare -a proyectSymlinks
	declare proyectInfo

	while getopts $optstring option
	do
		case $option in
			# $option $OPTARG $OPTIND
			p )
				proyectName=$OPTARG
				;;
			s )
				svnURL=$OPTARG
				;;
			u )
				svnUsername=$OPTARG
				;;
			n )
				infoProyectName=$OPTARG
				;;
			d )
				infoProyectDescription=$OPTARG
				;;
		esac
	done

	shift $(($OPTIND - 1))

	if [ -n "${proyectName}" ]
	then
		proyectDir="${PROYECTSBASE}/${proyectName}"
		proyectDirectories=( bin deploy doc download etc extra lib share svn tmp var var/log var/run var/www )
		proyectFiles=( "bin/${proyectName}Enable.sh" "bin/${proyectName}Disable.sh" )
		proyectSymlinks=( "${proyectDir}/share" "${WORKBASE}/share/proyects/${proyectName}" )

		mkdir $proyectDir

		# PREAPPEND PROYECT DIRECTORY TO ALL THE DIRECTORIES THAT WILL BE CREATED
		work.createDirectories -p $proyectDir ${proyectDirectories[@]}

		# PREAPPEND PROYECT DIRECTORY TO ALL THE FILES THAT WILL BE CREATED
		work.createFiles -p $proyectDir ${proyectFiles[@]}

		work.createSymlinks ${proyectSymlinks[@]}

		if [ -n "${svnURL}" ]
		then
			if [ -n "${svnUsername}" ]
			then
				svnParams="--username ${svnUsername}"
			fi
			svn checkout $svnURL "${proyectDir}/svn" $svnParams
		fi

# PROYECT INFO >
(
cat <<EOF
name: $infoProyectName
description: $infoProyectDescription
svn: $svnURL $svnParams
EOF
) > "${proyectDir}/info"
# < PROYECT INFO

	fi

	return $exeStatus
}

function work.proyect.delete() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"
	declare userResponse

	if [ $(work.proyect.exist $proyectName) == $TRUE ]
	then
		printf "Are you sure you want to remove proyect \"${proyectName}\"? (y/n) : "
		read userResponse
		if [ $userResponse == 'y' ]
		then
			rm -f "${WORKBASE}/share/proyects/${proyectName}"
			rm -rf $proyectDir
		fi
	fi

	return $exeStatus
}

function work.proyect.exist() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"

	if [ -n "${1}" -a -d "${proyectDir}" ]
	then
		echo 1
  else
		echo 0
  fi

  return $exeStatus
}

function work.proyect.info() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"

	if [ $(work.proyect.exist $proyectName) == $TRUE -a -f "${proyectDir}/info" ]
  then
		cat ${proyectDir}/info
  fi

	return $exeStatus
}

function work.proyect.cd() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS
	
	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"
	
	if [ -n "$proyectName" ]
	then
		if [ $(work.proyect.exist $1) == $TRUE ]
		then
			cd $proyectDir
		fi
	else
		cd $PROYECTSBASE
	fi

	return $exeStatus
}

function work.proyect.list() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName
	declare -a params
	declare -i paramIte=0

	for arg in $@
	do
		if [ -n "$(echo $arg | grep \-)" ]
		then
			params[paramIte]=$arg
			((paramIte++))
		else
			proyectName=$arg
		fi
	done

	if [ -n "$proyectName" ]
	then
		if [ $(work.proyect.exist $proyectName) == $TRUE ]
		then
				ls $params "${PROYECTSBASE}/${proyectName}"
		fi
  else
		ls $params $PROYECTSBASE
  fi

	return $exeStatus
}

function work.proyect.exeCmd() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"
	declare cmd

	if [ $(work.proyect.exist $proyectName) == $TRUE ]
	then
		cmd="${proyectDir}/${2}"
		if [ -f "${cmd}" ]
		then
			shift 2
			$cmd $@
			exeStatus=$?
		fi
	fi

	return $exeStatus
}

function work.proyect.getEnableFilePath() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"
	declare proyectEnableCmd

	if [ $(work.proyect.exist $proyectName) == $TRUE ]
	then
		proyectEnableCmd="${proyectDir}/bin/${proyectName}Enable.sh"
		if [ -f "${proyectEnableCmd}" ]
		then
			echo $proyectEnableCmd
			exeStatus=$?
		fi
	fi

	return $exeStatus
}

function work.proyect.getDisableFilePath() {
	declare -r TRUE=1
	declare -r FALSE=0
	declare -i exeStatus=$EXIT_SUCCESS

	declare proyectName=$1
	declare proyectDir="${PROYECTSBASE}/${proyectName}"
	declare proyectDisableCmd

	if [ $(work.proyect.exist $proyectName) == $TRUE ]
	then
		proyectDisableCmd="${proyectDir}/bin/${proyectName}Disable.sh"
		if [ -f "${proyectDisableCmd}" ]
		then
			echo $proyectDisableCmd
			exeStatus=$?
		fi
	fi

	return $exeStatus
}

# < CLASS WORK.PROYECT

# GLOBAL VARIABLES >
declare -x WORKBASE=~/work; WORKBASE=$(work.escapeSpaces $WORKBASE)
declare -x PROYECTSBASE="${WORKBASE}/proyects"
declare -x PATH="${PATH}:${WORKBASE}/bin"
declare -x EXIT_SUCCESS=0
# < GLOBAL VARIABLES

# LOCAL VARIABLES >
declare optstring="p:"
declare exeStatus=$EXIT_SUCCESS

declare proyect
declare proyects
declare proyectEnableCmd
# < LOCAL VARIABLES

if (($# == 0))
then
	proyects=$(ls $PROYECTSBASE)
else
	while getopts $optstring option
	do
		case $option in
			# $option $OPTARG $OPTIND
			p )
				proyects=$(echo $OPTARG | tr ',' '\n')
				;;
		esac
	done
fi

work.create

for proyect in $proyects
do
	proyectEnableCmd=$(work.proyect.getEnableFilePath $proyect)
	if [ -n "$proyectEnableCmd" ]
	then
		source $proyectEnableCmd
		exeStatus=$?; if (($exeStatus != 0)); then break; fi
	fi
done

# UNSET LOCAL VARIABLES >
unset optstring
unset thisScript
unset exeStatus

unset proyect
unset proyects
unset proyectEnableCmd
# < UNSET LOCAL VARIABLES

# ALIAS >
alias ll='ls -FhloX --color'
alias ls+='ls -lhart -F --color=none|less'
alias less='less -SN'
alias mv='mv -i'
alias cp='cp -i'
alias rm='rm -i'
# < ALIAS

# PROMPT >
declare -x PS1='[\u@\h:\w]\$ '
declare -x PS1='[\u@\h:\W] > '
# < PROMPT

